/*  Handles.cpp
 *
 *  Copyright (C) 2013  Jaye Evins <evins@snaught.com>
 *
 *  This file is part of gLabels-qt.
 *
 *  gLabels-qt is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  gLabels-qt is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with gLabels-qt.  If not, see <http://www.gnu.org/licenses/>.
 */


#include "Handle.h"

#include "ModelObject.h"

#include <QColor>
#include <QDebug>


namespace glabels
{

	namespace model
	{

		//
		// Private
		//
		namespace
		{
			const double handlePixels             = 7;
			const double handleOutlineWidthPixels = 1;

			const QColor handleFillColor( 0,  192,  0,  96 );
			const QColor originHandleFillColor( 192,  0,  0,  96 );
			const QColor handleOutlineColor( 0,  0,   0,  192 );
		}


		///
		/// Handle Constructor
		///
		Handle::Handle( ModelObject* owner, Location location )
			: mOwner(owner), mLocation(location)
		{
			// empty
		}


		///
		/// Is Handle null?
		///
		bool Handle::isNull() const
		{
			return mLocation == NULL_HANDLE;
		}


		///
		/// Handle owner
		///
		ModelObject* Handle::owner() const
		{
			return mOwner;
		}


		///
		/// Handle location
		///
		Handle::Location Handle::location() const
		{
			return mLocation;
		}


		///
		/// Draw Handle
		///
		void Handle::draw( QPainter* painter, double scale ) const
		{
			switch ( mLocation )
			{
			case NW:
				drawAt( painter, scale, 0, 0, originHandleFillColor );
				break;
			case N:
				drawAt( painter, scale, mOwner->w()/2, 0, handleFillColor );
				break;
			case NE:
				drawAt( painter, scale, mOwner->w(), 0, handleFillColor );
				break;
			case E:
				drawAt( painter, scale, mOwner->w(), mOwner->h()/2, handleFillColor );
				break;
			case SE:
				drawAt( painter, scale, mOwner->w(), mOwner->h(), handleFillColor );
				break;
			case S:
				drawAt( painter, scale, mOwner->w()/2, mOwner->h(), handleFillColor );
				break;
			case SW:
				drawAt( painter, scale, 0, mOwner->h(), handleFillColor );
				break;
			case W:
				drawAt( painter, scale, 0, mOwner->h()/2, handleFillColor );
				break;
			case P1:
				drawAt( painter, scale, 0, 0, originHandleFillColor );
				break;
			case P2:
				drawAt( painter, scale, mOwner->w(), mOwner->h(), handleFillColor );
				break;
			default:
				qWarning() << "Unknown Handle location";
				break;
			}
		}


		///
		/// Handle Path
		///
		QPainterPath Handle::path( double scale ) const
		{
			switch ( mLocation )
			{
			case NW:
				return pathAt( scale, 0, 0 );
				break;
			case N:
				return pathAt( scale, mOwner->w()/2, 0 );
				break;
			case NE:
				return pathAt( scale, mOwner->w(), 0 );
				break;
			case E:
				return pathAt( scale, mOwner->w(), mOwner->h()/2 );
				break;
			case SE:
				return pathAt( scale, mOwner->w(), mOwner->h() );
				break;
			case S:
				return pathAt( scale, mOwner->w()/2, mOwner->h() );
				break;
			case SW:
				return pathAt( scale, 0, mOwner->h() );
				break;
			case W:
				return pathAt( scale, 0, mOwner->h()/2 );
				break;
			case P1:
				return pathAt( scale, 0, 0 );
				break;
			case P2:
				return pathAt( scale, mOwner->w(), mOwner->h() );
				break;
			default:
				qWarning() << "Unknown Handle location";
				return QPainterPath(); // Empty
				break;
			}
		}


		///
		/// Draw Handle at x,y
		///
		void Handle::drawAt( QPainter* painter,
		                     double    scale,
		                     Distance  x,
		                     Distance  y,
		                     QColor    color ) const
		{
			painter->save();

			painter->translate( x.pt(), y.pt() );

			double s = 1.0 / scale;

			QPen pen( handleOutlineColor );
			pen.setCosmetic( true );
			pen.setWidth( handleOutlineWidthPixels );

			painter->setPen( pen );
			painter->setBrush( color );

			painter->drawRect( QRectF( -s*handlePixels/2.0, -s*handlePixels/2.0,
			                           s*handlePixels, s*handlePixels ) );

			painter->restore();
		}


		///
		/// Create Handle path at x,y
		///
		QPainterPath Handle::pathAt( double   scale,
		                             Distance x,
		                             Distance y ) const
		{
			QPainterPath path;

			double s = 1/scale;

			path.addRect( -s*handlePixels/2, -s*handlePixels/2, s*handlePixels, s*handlePixels );
			path.translate( x.pt(), y.pt() );
	
			return path;
		}


	}

}
